/**
**********************************************************************************************************************************************************************************************************************************
* @file:	ModBuildin.h
* @author:	zinface
* @date:	2021年11月10日 15:35:49 星期三
* @brief:	FinalMod 提供的内建模块功能
**********************************************************************************************************************************************************************************************************************************
**/

#include "ModBuildin.h"

#include <stdio.h>    // printf FinalMod Loader Info

FinalC_Object_Size(ModStruct);

FinalC_Object_Create_Define(ModStruct) {
    ModStruct *fms = calloc(1, ModStructSize());
    fms->path = NULL;
    fms->name = NULL;

// FinalMod META _ WRAP
    fms->meta = NULL;
    fms->wrap = NULL;
    return fms;
}

ModStruct* createModStructWithMeta(const char *path, const char *name) {
    ModStruct *fms = createModStruct();
    fms->mod.dl = NULL;
    fms->mod.isLoad = false;
    fms->path = path;
    fms->name = name;
    return fms;
}

// ------------------------------------------ FinalModLoader

bool modStructLoader(ModStruct *fms) {
    if ((fms->mod.dl = FinalMod_Module_Open(fms->path, Delay)) != NULL) {
        fms->mod.isLoad = true;
        return true;
    }
    modStructLoaderFailMessage();
    fms->mod.isLoad = false;
    return false;
}

bool modStructUnloader(ModStruct *fms) {
    if (fms->mod.dl != NULL && fms->mod.isLoad) {
        FinalMod_Module_Close(fms->mod.dl);
        fms->mod.isLoad = false;
        fms->mod.dl = NULL;
        return true;
    }
    return false;
}

/**
 * 加载指定的符号数据
 * 
 * @return 返回成功加载的部分
 */
void * modStructLoaderSym(ModStruct *fms, const char *sym) {
    void *dl_sym = NULL;
    if (fms->mod.isLoad) {
        dl_sym = FinalMod_Module_ReadSym(fms->mod.dl, sym);
        if (dl_sym == NULL) {
            modStructLoaderFailMessage();
        }
    }
    return dl_sym;
}

/**
 * 加载 FinalMod Meta 结构信息
 * 
 * @return 返回加载是否成功
 */
bool modStructLoaderFinalModMeta(ModStruct *fms) {
   if (modStructLoader(fms)) {
       fms->meta = modStructLoaderSym(fms, FinalMod_META_SYM);
       if (fms->meta != NULL) {
#if FinalMod_DEBUG
           printf("[FinalMod Meta Info]\n\t"
                "FinalMod Name: %s\n\t"
                "FinalMod Description: %s\n\t"
                "FinalMod Version: %s\n",
                fms->meta->meta_name,
                fms->meta->meta_descript,
                fms->meta->meta_version);
#endif  // FinalMod_DEBUG
           return true;
       }
   }
   modStructLoaderFailMessage();
   return false;
}

/**
 * 加载 FinalMod Wrap 结构信息
 * 
 */
bool modStructLoaderFinalModWrap(ModStruct *fms) {
    if (fms->mod.isLoad) {
        fms->wrap = modStructLoaderSym(fms, FINALMOD_WRAP_SYM);
        if (fms->wrap != NULL) {
#if FinalMod_DEBUG
            printf("[FinalMod Wrap Info]\n\t"
                "Wrap Name: %s\n\t"
                "Wrap Description: %s\n\t"
                "Wrap Data: 0x%x\n",
                fms->wrap->wrap_name,
                fms->wrap->wrap_descript,
                (uint*)fms->wrap->wrap_data);
#endif  // FinalMod_DEBUG 
            return true;
        }
    }
    modStructLoaderFailMessage();
    return false;
}

void modStructLoaderFailMessage() {
// #ifdef  Debug
    printf("%s\n", loadFailMessage());
// #endif  //DEBUG
}